﻿using System;
using System.Collections.Generic;
using System.Text;
using AKMII.DMRA.DataAccess;
using AKMII.DMRA.Common;
using AKMII.DMRA.Business.Service;
using AKMII.DMRA.Business.Rule;
namespace AKMII.DMRA.Business.Management
{
    public class LoginManager
    {
        private UserAccessor userAccessor;

        public LoginManager()
        {
            userAccessor = new UserAccessor();
        }

        public string ValidateNewPassword(string userId, string password)
        {
            User user = null;
            try
            {
                user = userAccessor.GetUserById(userId);
                if (user != null)
                {
                    if (user.Password == password)
                        return "The password must not equals to the current one";
                    else if (userAccessor.IsPasswordUsed(userId, password))
                        return "The password must not be used in the past 3 times";
                }
            }
            catch (Exception ex)
            {
                Logger.Error("Exception occurs in Validating new password", ex);
            }
            return "";
        }

        public User Login(string userId, string password, int agentNum)
        {
            User user = null;

            try
            {
                user = userAccessor.GetUserById(userId);

                if (user != null)
                {
                    if (user.Status == UserStatus.Inactive || user.Status == UserStatus.Unavailable)
                    {
                        user.LoginStatus = LoginStatus.AccountLocked;
                        SentMailIfAccoudtLocked(userId);
                    }
                    else
                    {
                        if (password == user.Password)
                        {
                            user.LoginStatus = LoginStatus.Success;

                            if (user.LastLoginTime != null)
                            {
                                if ((DateTime.Now.Date - user.LastLoginTime.Value.Date).Days > 45)
                                {
                                    user.LoginStatus = LoginStatus.AccountLocked;
                                    SentMailIfAccoudtLocked(userId);
                                    userAccessor.UpdateUserStatusById(user.Id,
                                        Convert.ToInt32(UserStatus.Inactive));
                                }
                            }
                        }
                        else
                        {
                            user.LoginStatus = LoginStatus.PasswordIncorrect;
                        }
                    }
                }
                else
                {
                    user = new User();
                    user.LoginStatus = LoginStatus.AccountNotExist;
                }
            }
            catch (Exception ex)
            {
                Logger.Error("Exception occurs in login", ex);
                user = new User();
                user.LoginStatus = LoginStatus.Failed;
            }

            return user;
        }

        public void UpdateUserByLoginStatus(User user)
        {
            try
            {
                switch (user.LoginStatus)
                {
                    case LoginStatus.AccountLocked:
                        break;
                    case LoginStatus.AccountNotExist:
                        break;
                    case LoginStatus.PasswordIncorrect:
                        userAccessor.UpdateLoginFailedTimes(user.Id, user.FailedLoginTimes + 1);
                        break;
                    case LoginStatus.Failed:
                        break;
                    case LoginStatus.Success:
                        userAccessor.UpdateUserForLoginSuccess(user.Id, DateTime.Now, user.AgentNumber);
                        break;
                    default:
                        break;
                }
            }
            catch (Exception ex)
            {
                Logger.Error("Exception occurs in update user by login status", ex);
            }
        }

        public bool IsNeedChangePassword(string userId, DateTime? lastLoginTime)
        {
            bool result = false;

            if (lastLoginTime != null)
            {
                DateTime? datetime = null;
                datetime = userAccessor.GetLastMoifiedPasswordTime(userId);

                if (datetime != null)
                {
                    int duration = (DateTime.Now.Date - datetime.Value.Date).Days;
                    if (duration > 90)
                    {
                        result = true;
                    }
                }
            }
            else
            {
                result = true;
            }

            return result;
        }

        public bool RejectChangePassword(User user)
        {
            bool result = false;
            try
            {
                result = userAccessor.UpdateGraceLoginTimes(user.Id, user.GraceLoginTimes + 1);
            }
            catch (Exception ex)
            {
                Logger.Error("Exception occurs in update user by login status", ex);
            }

            return result;
        }

        public void SentMailIfAccoudtLocked(string UserID)
        {
            Mail AdminMail = new Mail();
            AdminMail.Subject = Constants.MailSubjectAccountLock;
            UserAccessor accessor = new UserAccessor();
            AdminMail.Recipients = accessor.GetMailAddress(UserType.Administrator);
            AdminMail.Content = string.Format(Constants.MailContentAccountLock, UserID, DateTime.Now.ToString());
            SmtpMailService smtp = new SmtpMailService(SystemConfiguration.CommonSetting.SmtpServer, SystemConfiguration.CommonSetting.SystemMailAddress, SystemConfiguration.CommonSetting.MailPassword);
            smtp.Send(AdminMail);
        }

        public bool UpdateAgentNumberByUserId(string userId, string division, string market, int agentNum)
        {
            bool result = false;

            try
            {
                result = userAccessor.UpdateAgentNumberByUserId(userId, division, market, agentNum);
            }
            catch (Exception ex)
            {
                Logger.Error("Exception occurs in update agent num by userid/divsion/market ", ex);
            }

            return result;
        }
    }
}
